package com.aibaixun.system.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.aibaixun.common.constant.ApiConstants;
import com.aibaixun.common.constant.CacheConstants;
import com.aibaixun.common.constant.Constants;
import com.aibaixun.common.core.domain.R;
import com.aibaixun.common.exception.ServiceException;
import com.aibaixun.common.utils.HttpUtils;
import com.aibaixun.common.utils.redis.RedisUtils;
import com.aibaixun.system.domain.dto.IndexStatisticsDto;
import com.aibaixun.system.domain.vo.*;
import com.aibaixun.system.service.DicmAlarmService;
import com.aibaixun.system.service.IndexStatisticsService;
import com.aibaixun.system.service.RequestLogService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 首页统计 服务层实现
 *
 * @author zhangyh
 */
@RequiredArgsConstructor
@Service
public class IndexStatisticsServiceImpl implements IndexStatisticsService {
    private static final Logger logger = LoggerFactory.getLogger(IndexStatisticsServiceImpl.class);

    @Autowired
    private DicmAlarmService dicmAlarmService;

    @Value("${commonConfig.isOut}")
    private Boolean isOut;

    /**
     * 公共入参组装
     * @param dto
     * @return
     */
    public String checkParamString(IndexStatisticsDto dto){
        StringBuilder paramString = new StringBuilder();
        paramString.append("?");
        if(dto.getType().intValue() != 1 && dto.getAddressId() == null){
            throw new ServiceException("请指定查询具体地点！");
        }
        paramString.append("type="+dto.getType());
        if(dto.getAddressId() != null){
            paramString.append("&addressId="+dto.getAddressId());
        }
        if(dto.getDataType() != null){
            paramString.append("&dataType="+dto.getDataType());
        }
        return paramString.toString();
    }

    @Override
    public R<PowerAndCabinetStatisticsVo> getPowerAndCabinet(IndexStatisticsDto dto) {
        String paramString = checkParamString(dto);
        PowerAndCabinetStatisticsVo dataVo = new PowerAndCabinetStatisticsVo();
        if(isOut){
            return R.ok(dataVo);
        }
        JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
            +ApiConstants.GET_POWER_CABINET_STATISTICS+paramString);
        logger.info("获取冷量电力统计返回结果:{}"+ JSONUtil.parse(jsonObject));
//        requestLogService.recordResutData("冷电容量统计",jsonObject);
        if(jsonObject == null){
            return R.ok(dataVo);
        }
        if(jsonObject.getInteger("code") == null || jsonObject.getInteger("code").intValue() != 200){
            if(jsonObject.getInteger("code").intValue() == 401){
                RedisUtils.deleteObject(CacheConstants.OPEN_API_TOKEN+"gs001");
                this.getPowerAndCabinet(dto);
            }else{
                return R.ok(dataVo);
            }
        }
        dataVo = JSONObject.parseObject(JSON.toJSONString(jsonObject.get("data")),PowerAndCabinetStatisticsVo.class);
        return R.ok(dataVo);
    }

    @Override
    public R<AlarmStatisticsVo> getAlarm(IndexStatisticsDto dto) {
        AlarmStatisticsVo dataVo = dicmAlarmService.getAlarmStatistics(dto);

//        String paramString = checkParamString(dto);
//        AlarmStatisticsVo dataVo = new AlarmStatisticsVo();
//        JSONObject jsonObjectOri = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
//            +ApiConstants.GET_ALARM_STATISTICS+paramString);
////        requestLogService.recordResutData("告警统计",jsonObjectOri);
//        if(jsonObjectOri == null){
//            return R.ok(dataVo);
//        }
//        if(jsonObjectOri.getInteger("code") == null || jsonObjectOri.getInteger("code").intValue() != 200){
//            if(jsonObjectOri.getInteger("code").intValue() == 401){
//                RedisUtils.deleteObject(CacheConstants.OPEN_API_TOKEN+"gs001");
//                this.getAlarm(dto);
//            }else{
//                return R.ok(dataVo);
//            }
//        }
//
//        JSONObject jsonObject = jsonObjectOri.getJSONObject("data");
//        /**
//         * U位告警数
//         */
//        int uAlarm = 0;
//        /**
//         * 动环告警
//         */
//        int sealHeadAlarm = 0;
//        /**
//         * 故障告警
//         */
//        int faultAlarm = 0;
//        /**
//         * 一级
//         */
//        int levelOneAlarm = 0;
//        /**
//         * 二级
//         */
//        int levelTwoAlarm = 0;
//        /**
//         * 三级
//         */
//        int levelThreeAlarm = 0;
//        /**
//         * 四级
//         */
//        int levelFourAlarm = 0;
//        /**
//         * 告警总数
//         */
//        int totalAlarm = 0;
//
//        //U位告警
////        JSONObject uJson = jsonObject.getJSONObject("UAlarm");
////        int uCount1 = uJson.getIntValue("level1");
////        int uCount2 = uJson.getIntValue("level2");
////        int uCount3 = uJson.getIntValue("level3");
////        int uCount4 = uJson.getIntValue("level4");
//
//        int uCount1 = 0;
//        int uCount2 = 0;
//        int uCount3 = 0;
//        int uCount4 = 0;
//
//        //动环告警
//        JSONObject sealHeadJson = jsonObject.getJSONObject("DHAlarm");
//        int sealHeadCount1 = sealHeadJson.getIntValue("level1");
//        int sealHeadCount2 = sealHeadJson.getIntValue("level2");
//        int sealHeadCount3 = sealHeadJson.getIntValue("level3");
//        int sealHeadCount4 = sealHeadJson.getIntValue("level4");
//
//        //故障告警
//        JSONObject faultJson = jsonObject.getJSONObject("GZAlarm");
//        int faultCount1 = faultJson.getIntValue("level1");
//        int faultCount2 = faultJson.getIntValue("level2");
//        int faultCount3 = faultJson.getIntValue("level3");
//        int faultCount4 = faultJson.getIntValue("level4");
//
//        uAlarm = (uCount1+uCount2+uCount3+uCount4);
//        sealHeadAlarm = (sealHeadCount1+sealHeadCount2+sealHeadCount3+sealHeadCount4);
//        faultAlarm = (faultCount1+faultCount2+faultCount3+faultCount4);
//        levelOneAlarm = (uCount1+sealHeadCount1+faultCount1);
//        levelTwoAlarm = (uCount2+sealHeadCount2+faultCount2);
//        levelThreeAlarm = (uCount3+sealHeadCount3+faultCount3);
//        levelFourAlarm = (uCount4+sealHeadCount4+faultCount4);
//        totalAlarm = (uAlarm+sealHeadAlarm+faultAlarm);
//        dataVo.setFaultAlarm(faultAlarm);
//        dataVo.setUAlarm(uAlarm);
//        dataVo.setSealHeadAlarm(sealHeadAlarm);
//        dataVo.setLevelOneAlarm(levelOneAlarm);
//        dataVo.setLevelTwoAlarm(levelTwoAlarm);
//        dataVo.setLevelThreeAlarm(levelThreeAlarm);
//        dataVo.setLevelFourAlarm(levelFourAlarm);
//        dataVo.setTotalAlarm(totalAlarm);
        return R.ok(dataVo);
    }

    @Override
    public R<WorkOrderStatisticsVo> getWorkOrder(IndexStatisticsDto dto) {
        String paramString = checkParamString(dto);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String endTime = LocalDateTime.now().format(formatter);
        String startTime = LocalDateTime.now().minusDays(30).format(formatter);
        WorkOrderStatisticsVo dataVo = new WorkOrderStatisticsVo();
        if(isOut){
            return R.ok(dataVo);
        }
        JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
//            +ApiConstants.GET_WORK_ORDER_STATISTICS+paramString+"\\&startTime="+startTime+"\\&endTime="+endTime);
            +ApiConstants.GET_WORK_ORDER_STATISTICS+paramString);
//        requestLogService.recordResutData("工单统计",jsonObject);
        if(jsonObject == null){
            return R.ok(dataVo);
        }
        if(jsonObject.getInteger("code") == null || jsonObject.getInteger("code").intValue() != 200){
            if(jsonObject.getInteger("code").intValue() == 401){
                RedisUtils.deleteObject(CacheConstants.OPEN_API_TOKEN+"gs001");
                return this.getWorkOrder(dto);
            }else{
                return R.ok(dataVo);
            }
        }
        JSONArray jsonArray = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("data")));

        /**
         * 总数量
         */
        int totoal = 0;
        /**
         * 状态一（运行中）
         */
        int state1 = 0;
        /**
         * 状态二（已归档）
         */
        int state2 = 0;
        /**
         * 状态三（已作废）
         */
        int state3 = 0;
        /**
         * 状态四（强制归档）
         */
        int state4 = 0;
        for (Object o : jsonArray) {
            JSONObject jsonData = JSONObject.parseObject(o.toString());
            totoal = (totoal+jsonData.getIntValue("total"));
            state1 = (state1+jsonData.getIntValue("unclearAmounts"));
            state2 = (state2+jsonData.getIntValue("clearAmounts"));
            state3 = (state3+jsonData.getIntValue("cancelAmounts"));
            state4 = (state4+jsonData.getIntValue("forceAmounts"));
        }
        dataVo.setTotoal(totoal);
        dataVo.setState1(state1);
        dataVo.setState2(state2);
        dataVo.setState3(state3);
        dataVo.setState4(state4);

        return R.ok(dataVo);
    }

    @Override
    public R<List<EnergyPueStatisticsVo>> getEnergyPue(IndexStatisticsDto dto) {
        String paramString = checkParamString(dto);
        paramString = (paramString+"&dataType=1&siteId="+dto.getAddressId());
        List<EnergyPueStatisticsVo> result = new LinkedList<>();
        if(isOut){
            return R.ok(result);
        }
        JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
            +ApiConstants.GET_PUE_STATISTICS+paramString);
//        requestLogService.recordResutData("能效统计",jsonObject);
        if(jsonObject == null){
            return R.ok(result);
        }
        if(jsonObject.getInteger("code") == null || jsonObject.getInteger("code").intValue() != 200){
            if(jsonObject.getInteger("code").intValue() == 401){
                RedisUtils.deleteObject(CacheConstants.OPEN_API_TOKEN+"gs001");
                return this.getEnergyPue(dto);
            }else{
                return R.ok(result);
            }
        }
        JSONArray jsonArray = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("data")));

        //暂时写死，只返回8个微魔方的数据
        Map<String,String> roomMap = new HashedMap();
        roomMap.put("双层双联1模方","1#");
        roomMap.put("双层双联2模方","2#");
        roomMap.put("双层双联3模方","3#");
        roomMap.put("双层双联4模方","4#");
        roomMap.put("双层双联5模方","5#");
        roomMap.put("双层双联6模方","6#");
        roomMap.put("双层双联7模方","7#");
        roomMap.put("双层双联8模方","8#");

        for (Object o : jsonArray) {
            JSONObject jsonData = JSONObject.parseObject(o.toString());
            String addressName = jsonData.getString("addressName");
            if(dto.getType().intValue() != Constants.INT_1 && roomMap.get(addressName) == null){
                continue;
            }
            EnergyPueStatisticsVo dataVo = new EnergyPueStatisticsVo();
            dataVo.setAddressName(addressName);

            if(dto.getType().intValue() != Constants.INT_1){
                dataVo.setAddressName(roomMap.get(addressName));
            }
            dataVo.setData(jsonData.getString("data"));
            result.add(dataVo);
        }

        result = result.stream()
            .sorted(Comparator.comparing(EnergyPueStatisticsVo::getAddressName))
            .collect(Collectors.toList());

        return R.ok(result);
    }

    @Override
    public R<List<TopPueStatisticsVo>> getTopPue(IndexStatisticsDto dto) {
        String paramString = checkParamString(dto);
        List<TopPueStatisticsVo> result = new LinkedList<>();
        if(isOut){
            return R.ok(result);
        }
        JSONObject jsonObject = HttpUtils.sendGetRequest(ApiConstants.IP_ADDRESS
            +ApiConstants.GET_TOP_PUE_STATISTICS+paramString);
//        requestLogService.recordResutData("能效TOP5统计",jsonObject);
        if(jsonObject == null){
            TopPueStatisticsVo dataVo1 = new TopPueStatisticsVo();
            TopPueStatisticsVo dataVo2 = new TopPueStatisticsVo();
            TopPueStatisticsVo dataVo3 = new TopPueStatisticsVo();
            TopPueStatisticsVo dataVo4 = new TopPueStatisticsVo();
            TopPueStatisticsVo dataVo5 = new TopPueStatisticsVo();
            result.add(dataVo1);
            result.add(dataVo2);
            result.add(dataVo3);
            result.add(dataVo4);
            result.add(dataVo5);

            return R.ok(result);
        }
        if(jsonObject.getInteger("code") == null || jsonObject.getInteger("code").intValue() != 200){
            if(jsonObject.getInteger("code").intValue() == 401){
                RedisUtils.deleteObject(CacheConstants.OPEN_API_TOKEN+"gs001");
                this.getTopPue(dto);
            }else{
                return R.ok(result);
            }
        }
        JSONArray jsonArray = JSONObject.parseArray(JSON.toJSONString(jsonObject.get("data")));
        for (Object o : jsonArray) {
            JSONObject jsonData = JSONObject.parseObject(o.toString());
            TopPueStatisticsVo dataVo = new TopPueStatisticsVo();
            dataVo.setAddressName(jsonData.getString("addressName"));
            dataVo.setPue(jsonData.getString("pue"));
            dataVo.setAddressId(jsonData.getString("addressId"));
            dataVo.setItEnergy(jsonData.getString("itEnergy"));
            dataVo.setTotalEnergy(jsonData.getString("totalEnergy"));
            result.add(dataVo);
        }
        return R.ok(result);
    }

    @Override
    public List<QueryAlarmVo> queryAlarmList() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -7);
        Date time = calendar.getTime();
        String startTime = DateUtil.format(time, DatePattern.NORM_DATE_FORMATTER);
        String endTime = DateUtil.format(date, DatePattern.NORM_DATE_FORMATTER);
        return dicmAlarmService.queryAlarmList(startTime,endTime);
    }
}
